# -*- coding: utf-8 -*-
"""
Created on Sat Apr 22 15:57:57 2023

@author: simsh
"""

#!/usr/bin/python3

# Switch to a backend that doesn't need X

import matplotlib.pyplot as plt
import pandas as pd
import SMART


def add_plot(scenario_df, core_count):

    #add x-axis tick marks to graph
    minTotalUtil = core_count
    maxTotalUtil = core_count*2
    ticks=[]
    for j in range(minTotalUtil, maxTotalUtil+1):
        ticks.append(j)

    #what are the utilization points we need to plot?
    util=[]
    j=0
    while j * BIN_SIZE < maxTotalUtil:
        util.append(minTotalUtil+j*BIN_SIZE+BIN_SIZE/2)
        j+=1

    figure, axis =plt.subplots(2,2, figsize=(12,12))
    for taskUtilRange in TASK_UTIL_RANGES:
        util_df = scenario_df[
            (scenario_df['per_task_util_min'] == taskUtilRange[0]) &
            (scenario_df['per_task_util_max'] == taskUtilRange[1])
            ]
        best_rsa = ''
        for algo in range(SMART.Partition.OBLIVIOUS, SMART.Partition.AWARE_START_OBLIV+1):
            if algo == SMART.Partition.OBLIVIOUS:
                algoName="Oblivious"
                algoStyle='solid'
            elif algo == SMART.Partition.AWARE_START_THREAD:
                algoName="Greedy-Thread"
                algoStyle='dotted'
            elif algo == SMART.Partition.AWARE_START_PHYS:
                algoName="Greedy-Physical"
                algoStyle="dashed"
            elif algo == SMART.Partition.AWARE_START_OBLIV:
                algoName="Greedy-Mixed"
                algoStyle="dashdot"
            #get success rates for chosen scenario and algo
            successRates=[]
            algo_df = util_df[util_df['algo'] == algo]
            j=0
            #print("model: ", model)
            while j * BIN_SIZE < maxTotalUtil:
                # I'll have to clean up column names manually
                successRates.append(algo_df[str(j)].values[0])
                j +=1
            # is this the best algorithm?
            if algo_df['best_rsa'].values[0] == 1:
                best_rsa = str(round(algo_df['rsa'].values[0], 2))

            if taskUtilRange[0] == 0:
                col = 0
            else:
                col = 1
            if taskUtilRange[1] < 1:
                row = 0
            else:
                row = 1

            #graph the success rates vs. utilization
            axis[row, col].plot(util, successRates, label=algoName, linestyle=algoStyle)
            axis[row, col].set_ylim(0,1.02)
            axis[row, col].set_xlim(coreCount, 2*coreCount)
            axis[row, col].set_xlabel('Utilization')
            axis[row, col].set_ylabel('Schedulability Ratio')
            #plt.legend(algoName)
            full_header, name = write_header_and_name(coreCount, taskUtilRange[0], taskUtilRange[1], expected_score, prob_harm, best_rsa)
            axis[row, col].set_title(full_header)
            axis[row, col].legend()
            #axis.clf()
    # plt.show()

    figure.savefig(FOLDER_OUT + name + ".pdf")
    figure.tight_layout()
    figure.clf()


def write_header_and_name(coreCount, minTaskUtil, maxTaskUtil, expected_score, prob_harm, best_rsa):

    coreHeader=str(str(coreCount) + " Cores")
    distrib_header = str(expected_score) + ", h=" + str(prob_harm)
    if score_distro == SMART.FIXED:
        distrib_header = distrib_header + " , fixed"
    elif score_distro == SMART.EXPO:
        distrib_header = distrib_header + " , expo"
    util_header="Task Util. ~ U(" + str(minTaskUtil) + ", " + str(maxTaskUtil) + ")"
    rsa_header = "Best RSA: " + best_rsa
    full_header=coreHeader + ", " + util_header + " " + distrib_header + "\n" + rsa_header
    #name = " ".join([coreHeader, distrib_header, util_header, best_rsa])
    name = " ".join([coreHeader, distrib_header])
    return full_header, name

FOLDER_OUT = "Quads/"
#FILE_IN = "Apr28-samples 500/srt_schedTests_Apr28-bin0,2-samples500.csv"
FILE_IN = "srt_schedTests_Apr22-bin0,1-samples1000/srt_schedTests_Apr22-bin0,1-samples1000.csv"

#Apr 22 2100 uses bin size 0.2?
BIN_SIZE = 0.1
#BIN_SIZE = .10

#TASK_UTIL_RANGES=[(0, .4), (0, 1)]
TASK_UTIL_RANGES=[(0, .4), (.3, .7), (0, 1), (.6, 1)]
EXPECTED_SCORES = [0.2, 0.4, 0.6]
#EXPECTED_SCORES = [0.4]

df=pd.read_csv(FILE_IN)

# crazy nested for loop because I want to look at lines matching a single scenario at once
# I can't guarantee the order in which results will be in file.
for coreCount in [4,8]:
    #for taskUtilRange in TASK_UTIL_RANGES:
    for expected_score in EXPECTED_SCORES:
        for prob_harm in [0, 0.125, 0.25]:
            for degree_harm in [2]:
                for score_distro in [SMART.FIXED, SMART.EXPO]:

                    scenario_df = df[
                        (df['core_count'] == coreCount) &
                        #(df['per_task_util_min'] == taskUtilRange[0]) &
                        #(df['per_task_util_max'] == taskUtilRange[1]) &
                        (df['expected_score'] == expected_score) &
                        (df['prob_harm'] == prob_harm) &
                        (df['degree_harm'] == degree_harm) &
                        (df['score_distro'] == score_distro)
                        ]
                    # if we don't have any scenarios with current parameters
                    if scenario_df.shape[0] == 0:
                        continue

                    add_plot(scenario_df, coreCount)
                        #add_plot(coreCount, symDistrib, numPeriods, taskUtilRange, fileName)